{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# Loader机制\n",
    "- 加载Markdown\n",
    "- 加载CSV\n",
    "- 加载文件目录\n",
    "- 加载html\n",
    "- 加载JSON\n",
    "- 加载PDF"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "ad3e3c87b15643f9"
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "data": {
      "text/plain": "[Document(page_content='# 我是一个markdown加载示例\\n- 第一项目\\n- 第二个项目\\n- 第三个项目\\n\\n## 第一个项目\\nAI研习社最厉害专业的AI研究基地\\n\\n## 第二个项目\\nAIGC打造未来AI应用天地\\n\\n## 第三个项目\\nAI研习社是一个非常牛逼的AI媒体', metadata={'source': 'loader.md'})]"
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用loader加载Markdown文本\n",
    "from langchain.document_loaders import TextLoader\n",
    "\n",
    "loader = TextLoader(\"loader.md\")\n",
    "loader.load()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-12T14:53:49.447926300Z",
     "start_time": "2024-05-12T14:53:49.426935600Z"
    }
   },
   "id": "e2b7ec185eaf2bd4"
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Document(page_content='\\n\\n\\n名称\\n宏图科技发展有限公司\\n\\n\\n注册地址\\n江苏省南京市雨花台区软件大道101号\\n\\n\\n成立日期\\n40679\\n\\n\\n法定代表人\\n李强\\n\\n\\n注册资本\\n人民币5000万元\\n\\n\\n员工人数\\n约200人\\n\\n\\n联系电话\\n025-88888888\\n\\n\\n电子邮箱\\ninfo@hongtutech.cn\\n\\n\\n资产总额\\n人民币1.2亿元，较上年同期下降30%\\n\\n\\n负债总额\\n人民币1.8亿元，较上年同期上升50%，资不抵债\\n\\n\\n营业收入\\n人民币3000万元，较上年同期下降60%\\n\\n\\n净利润\\n亏损人民币800万元，去年同期为盈利人民币200万元\\n\\n\\n现金流量\\n公司现金流量紧张，现金及现金等价物余额为人民币500万元，难以支撑日常运营\\n\\n\\n', metadata={'source': 'example\\\\fake.xlsx'})]\n"
     ]
    }
   ],
   "source": [
    "from langchain.document_loaders import DirectoryLoader\n",
    "# loader = DirectoryLoader(\"目录地址\", glob=\"指定加载说明格式的文件\")\n",
    "loader = DirectoryLoader(path = \"./example/\", glob=\"*.xlsx\")\n",
    "docs = loader.load()\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-12T14:56:39.092721700Z",
     "start_time": "2024-05-12T14:56:39.070155300Z"
    }
   },
   "id": "96f04478e1807f88"
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "outputs": [
    {
     "data": {
      "text/plain": "[Document(page_content='RAG:将检索与生成方式相结合来做生成任务 - 知乎首发于自然语言处理算法与实践切换模式写文章登录/注册RAG:将检索与生成方式相结合来做生成任务烛之文?a worker in NLP1、前言在上一篇<kNN-NER：利用knn近邻算法来做命名实体识别>提及到文中提出kNN-NER框架是一种检索式增强的方法（retrieval augmented methods），就去查看有关retrieval augmented的paper，了解其核心思想，觉得检索式增强的方法很适合许多业务场景使用，因其以一种简捷的方式将外部知识融于模型中去。今天就分享一篇来自Facebook AI Research的paper<Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks>，论文提出一种检索式增强生成方法，应用于知识密集型的NLP任务（如问答生成），该篇论文被2020年NeurIPS 会议接收。文中说到，以BERT之类的大规模预训练模型将很多事实知识信息存入模型中，可以看着是pre-trained parametric类型，尽管以fine-tuned方式在下游任务取得显著的成效，但这类方法仍存在无法精准地获取和操作知识的缺陷。而在上述提及的问题上，传统知识检索的方法能很好的应对，这类方法可以看着是non-parametric memory类型。于是，论文提出检索式增强生成方法（retrieval-augmented generation，RAG），主要思想就是将pre-trained parametric与non-parametric memory结合起来做语言生成任务，将两类模型集成起来提高任务处理效果。2、RAG方法上图为论文提出RAG模型的整体示意图。主要包括两大模块：一个检索器（Retriever， p_\\\\eta(z|x) ） + 一个生成器（Generator， p_\\\\theta(y_i|x,z,y_{1:i-1}) ）。前者包括query encoder和document index，分别负责query的编码和文档的索引；后者是一个seq2seq的生成模型。在检索中，使用的是最大内积搜索的方法（MIPS）来检索top-K相关文档。最后，把检索器输出的信息当成额外的文本信息，通过边际化的方式（marginalize）融于生成器中，生成最终的序列。在融合过程中，论文提出两种不同的方式：RAG-Sequence Model和RAG-Token Model，主要区别在于前者利用同一篇文档来生成所有序列；后者是用检索到的所有文档来生成序列。其计算方式如下：关于检索器 p_\\\\eta(z|x) ，由输入query x经过encoder得到编码向量q(x)，另外将知识库里的文档事先通过编码器得到文档编码向量d(z)，然后q(x)与d(z)做最大内积搜索到top-K相关文档，输出作为 p_\\\\eta(z|x) 。关于生成器 p_\\\\theta(y_i|x,z,y_{1:i-1}) ，论文中是用BART-large作为训练模型，然后将query x和检索到的z输入其中得到生成的序列文本。在解码过程中，RAG-Token Model可视为一个标准的自回归生成模型，按常规的beam search方式就可以解码；而在RAG-Sequence Model中，因为每个文档都生成一个序列，不能正常的beam search方式来解码。文中是对每个文档按beam search解码出一个序列，得到解码序列集合，针对每个生成序列，用其生成概率与 p_\\\\eta(z|x) 点乘得到一个概率score，取最大值对应的序列为最终输出。3、实验论文在四类Knowledge-Intensive 任务上进行实验，具体包括开放问答（Open-domain Question Answering ）、摘要式问答（Abstractive Question Answering） 、开放问题生成（Jeopardy Question Generation）、事实判断（Fact Verification ），并使用维基百科（包含2100万个文档）作为检索库。上表显示：在Open-domain Question Answering 任务上，论文提出的两个方法在4个数据集都取得新的最佳结果。上表显示，在Jeopardy Question Generation任务（Jeopardy数据集）上，RAG-Tok取得最优结果，且RAG都超过BART的表现；在Abstractive Question Answering任务（MSMARCO数据集）上，RAG模型都优于BART模型，但接近已有的最佳模型，其原因是论文在实验中没有利用数据集中包含文档 gold access信息；在Fact Verification任务上（FVR3,FVR2数据集） 上，对于3-way分类（FVR3），RAG比最优模型差4.3%，然而这类最优模型都是基于复杂的pipeline方法，需要大量的中间特征工程，而RAG不需要这些特征工程就可以达到接近的效果。此外，论文显示对比BART，RAG模型生成的文本更符合事实，更准确，且多样化。4、结语本次分享基于检索增强方式将外部知识融于生成任务中一个新的框架——RAG。对比T5 和 BART这类擅长处理生成任务的模型来说，RAG更新外部知识是不需要重新预训练，成本低；而对比pipeline方法，RAG利用外部知识并不需要构造负责的特征工程。总的来说，RAG方法可作为外部知识融合框架的一种有效实例。有兴趣可关注笔者公众号：自然语言处理算法与实践编辑于 2022-04-06 10:47深度学习（Deep Learning）机器学习检索数据库?赞同 16??添加评论?分享?喜欢?收藏?申请转载?文章被以下专栏收录自然语言处理算法与实践', metadata={'source': 'loader.html', 'title': 'RAG:将检索与生成方式相结合来做生成任务 - 知乎'})]"
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "  # 使用loader加载html文件\n",
    "from langchain.document_loaders import BSHTMLLoader\n",
    "loader = BSHTMLLoader(\"loader.html\")\n",
    "data = loader.load()\n",
    "data"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-12T15:05:48.145525200Z",
     "start_time": "2024-05-12T15:05:48.134090300Z"
    }
   },
   "id": "c3b8fa8a6cb50596"
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "outputs": [
    {
     "ename": "ImportError",
     "evalue": "jq package not found, please install it with `pip install jq`",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mModuleNotFoundError\u001B[0m                       Traceback (most recent call last)",
      "File \u001B[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\langchain\\document_loaders\\json_loader.py:43\u001B[0m, in \u001B[0;36mJSONLoader.__init__\u001B[1;34m(self, file_path, jq_schema, content_key, metadata_func, text_content)\u001B[0m\n\u001B[0;32m     42\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m---> 43\u001B[0m     \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mjq\u001B[39;00m  \u001B[38;5;66;03m# noqa:F401\u001B[39;00m\n\u001B[0;32m     44\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mImportError\u001B[39;00m:\n",
      "\u001B[1;31mModuleNotFoundError\u001B[0m: No module named 'jq'",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001B[1;31mImportError\u001B[0m                               Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[17], line 3\u001B[0m\n\u001B[0;32m      1\u001B[0m \u001B[38;5;66;03m# 使用loader加载json文件\u001B[39;00m\n\u001B[0;32m      2\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mlangchain\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mdocument_loaders\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m JSONLoader\n\u001B[1;32m----> 3\u001B[0m loader \u001B[38;5;241m=\u001B[39m JSONLoader(\n\u001B[0;32m      4\u001B[0m   file_path\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mloader.json\u001B[39m\u001B[38;5;124m\"\u001B[39m,\n\u001B[0;32m      5\u001B[0m   jq_schema\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m.template\u001B[39m\u001B[38;5;124m\"\u001B[39m,\n\u001B[0;32m      6\u001B[0m   text_content\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m\n\u001B[0;32m      7\u001B[0m )\n\u001B[0;32m      8\u001B[0m data \u001B[38;5;241m=\u001B[39m loader\u001B[38;5;241m.\u001B[39mload()\n\u001B[0;32m      9\u001B[0m data\n",
      "File \u001B[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\langchain\\document_loaders\\json_loader.py:45\u001B[0m, in \u001B[0;36mJSONLoader.__init__\u001B[1;34m(self, file_path, jq_schema, content_key, metadata_func, text_content)\u001B[0m\n\u001B[0;32m     43\u001B[0m     \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mjq\u001B[39;00m  \u001B[38;5;66;03m# noqa:F401\u001B[39;00m\n\u001B[0;32m     44\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mImportError\u001B[39;00m:\n\u001B[1;32m---> 45\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mImportError\u001B[39;00m(\n\u001B[0;32m     46\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mjq package not found, please install it with `pip install jq`\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m     47\u001B[0m     )\n\u001B[0;32m     49\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mfile_path \u001B[38;5;241m=\u001B[39m Path(file_path)\u001B[38;5;241m.\u001B[39mresolve()\n\u001B[0;32m     50\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_jq_schema \u001B[38;5;241m=\u001B[39m jq\u001B[38;5;241m.\u001B[39mcompile(jq_schema)\n",
      "\u001B[1;31mImportError\u001B[0m: jq package not found, please install it with `pip install jq`"
     ]
    }
   ],
   "source": [
    "  # 使用loader加载json文件\n",
    "from langchain.document_loaders import JSONLoader\n",
    "loader = JSONLoader(\n",
    "    file_path=\"loader.json\",\n",
    "    jq_schema=\".template\",\n",
    "    text_content=False\n",
    ")\n",
    "data = loader.load()\n",
    "data"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-12T15:13:18.029265600Z",
     "start_time": "2024-05-12T15:13:17.993345500Z"
    }
   },
   "id": "20ed687ad7e5364e"
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "outputs": [
    {
     "data": {
      "text/plain": "Document(page_content='蒂法介绍蒂法·洛克哈特（⽇语：ティファ・ロックハート，Tifa Rokkuhāto，英语：Tifa Lockhart）为电⼦游戏《最终幻想VII》及《最终幻想VII补完计划》相关作品中的虚构⻆⾊，由野村哲也创作和设计，此后也在多个游戏中客串登场。2014年东京电玩展上，星名美津纪cosplay《最终幻想VII 降临之⼦》中的蒂法·洛克哈特蒂法是克劳德的⻘梅⽵⻢，两⼈同为尼布鲁海姆出身。在⽶德加经营作为反抗组织“雪崩”根据地的酒馆“第七天堂”，并且是⼩有名⽓的招牌店员。擅⻓格⽃，以拳套为武器。本传7年前克劳德离开故乡从军时，曾许下约定“如果有危机时⼀定会保护她”。与爱丽丝相识之后，两⼈成为好友。第⼀个察觉克劳德记忆混乱的⼈，后来协助精神崩溃的克劳德重新找回真正的⾃⼰。本传的⼤战结束后，依⼤家的期待在战后新⽣的⽶德加再次开设第七天堂（原第七天堂因第柒区圆盘崩塌遭压毁），同时也照顾⼀群受到星痕症候群折磨的孩⼦们。蒂法被《纽约时报》称为“⽹络⼀代”的海报⼥郎，与劳拉·克罗夫特相⽐，她是电⼦游戏中坚强、独⽴和有吸引⼒的⼥性⻆⾊的典型代表。媒体普遍称赞其实⼒和外表，并称她为游戏世界中最好的⼥性⻆⾊之⼀。在《最终幻想VII》本传中，蒂法年龄20岁、身⾼167cm、⽣⽇5⽉3⽇、⾎型B型、出⽣地尼布尔海姆。登场《最终幻想VII》蒂法在《最终幻想VII》原版中⾸次亮相，是克劳德的⻘梅⽵⻢、第七天堂酒吧的看板娘、极端环境组织“雪崩”成员，该组织反抗巨型企业“神罗”因其⼤量抽取魔晄⽤作动⼒能源。在注意到克劳德的性格改变后，她说服克劳德加⼊雪崩，以密切关注他，并且跟随他追寻游戏中的对⼿萨菲罗斯。她⽆法阻⽌克劳德被萨菲罗斯操纵，在他的精神崩溃后，她帮助克劳德康复，并且两⼈意识到彼此间的相互感觉，最后与伙伴们⼀同击败了萨菲罗斯。[2]在闪回中可知，⼉时的蒂法⼀直是村中⼩孩的⼈⽓王。在⺟亲过世后，思念⺟亲的蒂法决定沿着⼩路⾛到他们故乡尼布尔海姆附近的⼀座⼭上，认为这样就能⻅到过世的⺟亲，原本跟着蒂法的其他⼩孩都在半路上因害怕⽽放弃，唯独克劳德仍坚定的在后⾯跟随，希望能在危机时保护蒂法。然⽽，他们俩都从⼭上跌落受伤，蒂法昏迷了⼀个星期，她的⽗亲认为克劳德对此负有责任[3]，甚为严令禁⽌克劳德再接近蒂法，但蒂法反⽽从此更在意克劳德，两⼈成为要好的玩伴。为了使⾃⼰变得更强⼤，克劳德最终选择离开尼布尔海姆，加⼊神罗，想要成为神罗的精英战⼠“神罗战⼠”（SOLDIER），但后来透露他主要是为了吸引蒂法的注意⼒。离开之前，蒂法与克劳德约定，当蒂法处于困境之中时，克劳德会回来救她。从克劳德离开之后，蒂法便开始留意神罗战⼠的消息，因为神罗战⼠都成为声名远播的知名⼈物，如果克劳德成为神罗战⼠，他的活跃也会⽴刻传回尼布尔海姆。数年后，在萨菲罗斯摧毁了尼布尔海姆之后，克劳德为了救蒂法，被萨菲罗斯刺⾄重伤。蒂法被她的武术教练赞⼲带到安全地带，幸存下来，最终到达⽶德加并遇⻅了“雪崩”的领导⼈巴雷特·华莱⼠。病愈后，蒂法加⼊了“雪崩”，为了给家乡被毁⼀事报仇。⼀天，她在⽕⻋站遇到了从魔晄炉中逃出来、精神⼀⽚混乱的克劳德，蒂法说服了他为巴雷特⼯作，以保证克劳德的安全以及和克劳德保持紧密关系。这是游戏开始的地⽅。在原版《最终幻想VII》中蒂法与爱丽丝关系友好，但会在某些时候争⻛吃醋，例如在神罗总部营救爱丽丝时，蒂法及巴雷特等⼀⾏失⼿被擒，若克劳德选择关⼼爱丽丝的话蒂法的对话中明显带有妒忌。在重制版中虽然删去这段情节，但保留了这种关系。在《最终幻想VII》的初稿中，蒂法是背景⼈物。她在“雪崩”中的作⽤是在幕后⽀持，在执⾏任务后为所有⼈加油⿎劲，并且对克劳德有特别的关⼼。据推测，她的背上有⼀块⼤的疤', metadata={'source': 'loader.pdf', 'page': 0})"
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用loader加载pdf文件\n",
    "from langchain.document_loaders import PyPDFLoader\n",
    "loader = PyPDFLoader(\"loader.pdf\")\n",
    "# data = loader.load()\n",
    "pages = loader.load_and_split()\n",
    "pages[0]"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-12T15:21:36.191515800Z",
     "start_time": "2024-05-12T15:21:36.114038900Z"
    }
   },
   "id": "c94958a59dbf3887"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   },
   "id": "84a616dbb27334dd"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
